<?php

/**
 * This is the model class for table "{{orders}}".
 *
 * The followings are the available columns in table '{{orders}}':
 * @property integer $order_id
 * @property string $order_key
 * @property string $cus_ckey
 * @property integer $payment_method
 * @property integer $order_date
 * @property integer $status
 * @property integer $apt_id
 * @property integer $s_id
 * @property double $s_price
 * @property double $tax
 * @property integer $staff_id
 * @property integer $biz_id
 * @property double $hotdeal_discount
 */
class Orders extends CActiveRecord
{

    const STATUS_PENDING           = 0;
    const STATUS_REFUND            = 1;
    const STATUS_CANCEL            = 2;
    const STATUS_COMPLETED         = 3;
    const STATUS_CONFIRMED         = 4;
    const STATUS_HOTDEAL           = 5;
    const STATUS_REDEEMED          = 7;
    const TYPE_NORMAL              = 0;
    const TYPE_HOTDEAL             = 1;
    const TYPE_FIRST               = 2;
    const TYPE_DISCOUNT_BY_PERCENT = 0;
    const TYPE_DISCOUNT_BY_MONEY   = 1;

    /**
     * @var int Order completed with webmaster, pay via paypal successfully
     */
    const STATUS_COMPLETED_webmaster = 5;
    const PAYMENT_CASH             = 0;
    const PAYMENT_CREDIT           = 1;
    const PAYMENT_PAYPAL           = 2;

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return Orders the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return '{{orders}}';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
        return array(
            array('payment_method, order_date, status, apt_id,s_id , staff_id, biz_id', 'numerical', 'integerOnly' => true),
            array('cus_ckey', 'length', 'max' => 50),
            array('order_key', 'length', 'max' => 32),
            array('s_price, hotdeal_discount,first_discount, other_discount', 'numerical'),
            // The following rule is used by search().
// Please remove those attributes that should not be searched.
            array('order_id, cus_ckey, payment_method, order_date, status,s_id, apt_id, staff_id, biz_id , tax, s_price, order_key, double, first_discount, other_discount', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
        $relations                 = parent::relations();
        $relations['service']      = array(
            self::BELONGS_TO, 'Service', 's_id'
        );
        $relations['appoint']      = array(
            self::BELONGS_TO, 'Appoint', 'apt_id'
        );
        $relations['receipt']      = array(
            self::HAS_ONE, 'Receipt', 'order_id'
        );
        $relations['staff']        = array(
            self::BELONGS_TO, 'Users', 'staff_id'
        );
        $relations['packageOrder'] = array(
            self::HAS_ONE, 'PackageOrder', 'order_id'
        );
        $relations['retailOrder']  = array(
            self::HAS_ONE, 'RetailOrder', 'order_id'
        );
        $relations['payment']      = array(
            self::HAS_ONE, 'Payment', 'order_id', 'condition' => "type=:t",
            'params'    => array(':t' => Payment::TYPE_APPOINT)
        );
        $relations['merchant']     = array(
            self::BELONGS_TO, 'Users', 'biz_id'
        );
        $relations['performs']     = array(
            self::HAS_MANY, 'PerformOrder', 'order_id'
        );
        return $relations;
    }

    public function getCustomer()
    {
        $customer = Customer::model()->find('ckey=:ckey', array(':ckey' => $this->cus_ckey));
        return $customer;
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'order_id'         => Yii::t('main', 'Order'),
            'cus_ckey'         => Yii::t('main', 'Customer'),
            'order_key'        => Yii::t('main', 'Order Ckey'),
            'payment_method'   => Yii::t('main', 'Payment Method'),
            'order_date'       => Yii::t('main', 'Order Date'),
            'status'           => Yii::t('main', 'Status'),
            'apt_id'           => Yii::t('main', 'Appointment'),
            's_id'             => Yii::t('main', 'Service'),
            'order_key'        => Yii::t('main', 'Order key'),
            's_price'          => Yii::t('main', 'Service price'),
            'staff_id'         => Yii::t('main', 'Staff'),
            'biz_id'           => Yii::t('main', 'Merchant'),
            'hotdeal_discount' => Yii::t('main', 'Hotdeal Discount'),
            'type'             => Yii::t('main', 'Type of deal'),
            'first_discount'   => Yii::t('main', '1st trial'),
            'other_discount'   => Yii::t('main', 'Other discount'),
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
// Warning: Please modify the following code to remove attributes that
// should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('order_id', $this->order_id);
        $criteria->compare('cus_ckey', $this->cus_ckey, true);
        $criteria->compare('order_key', $this->order_key, true);
        $criteria->compare('payment_method', $this->payment_method);
        $criteria->compare('order_date', $this->order_date);
        $criteria->compare('status', $this->status);
        $criteria->compare('apt_id', $this->apt_id);
        $criteria->compare('s_id', $this->s_id);
        $criteria->compare('s_price', $this->s_price);
        $criteria->compare('staff_id', $this->staff_id);
        $criteria->compare('biz_id', $this->biz_id);
        $criteria->compare('hotdeal_discount', $this->hotdeal_discount);
        $criteria->compare('first_discount', $this->first_discount);
        $criteria->compare('other_discount', $this->other_discount);

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }

    public function getPublicUrl()
    {
        return Yii::app()->createUrl('order/detail', array(
                    'pk' => $this->order_key,
        ));
    }

    /**
     * Get hotdeal price
     */
    public function getHotdealPrice()
    {
        if ($this->hotdeal_discount == 0)
        {
            return 0;
        }
        else
        {
            $discount_value = ($this->type == self::TYPE_DISCOUNT_BY_PERCENT ) ? ($this->hotdeal_discount * $this->s_price / 100) : $this->hotdeal_discount;

            return $discount_value;
        }
    }

    public function getFirstTimePrice()
    {
        if ($this->first_discount == 0)
        {
            return 0;
        }
        else
        {
            $discount_value = $this->first_discount * $this->s_price / 100;
            return $discount_value;
        }
    }

    /**
     * get price of service after calc tax, hotdeal, 1st
     */
    public function getPrice()
    {
        $discount       = $this->hotdeal_discount + $this->first_discount;
        $discount_value = ($this->type == self::TYPE_DISCOUNT_BY_PERCENT ) ? ($discount * $this->s_price / 100) : $discount;
        $final          = $this->s_price - $discount_value;
        return round($final, 2);
    }

    public function getFullLinkImage()
    {
        if ($this->service->user->photo)
            return Yii::app()->getBaseUrl(true) . "/" . $this->service->user->photo;
        else
            return Yii::app()->controller->assetDir . '/img/no-image.png';
    }

//    public function paymentMethod()
//    {
//        $payment = $this->listPaymentMethod();
//        return $payment[$this->payment_method];
//    }
//
//    /**
//     * 
//     * @return array list of payment method
//     */
//    public function listPaymentMethod()
//    {
//        return array(
//            self::PAYMENT_CASH => 'Cash',
//            self::PAYMENT_CREDIT => 'Credit card',
//            self::PAYMENT_PAYPAL => 'Paypal'
//        );
//    }

    public static function getListStatus()
    {
        return array(
            self::STATUS_PENDING   => Yii::t('main', 'Pending'),
            self::STATUS_REFUND    => Yii::t('main', 'Refund'),
            self::STATUS_CANCEL    => Yii::t('main', 'Canceled'),
            self::STATUS_COMPLETED => Yii::t('main', 'Completed'),
            self::STATUS_CONFIRMED => Yii::t('main', 'Confirmed'),
            self::STATUS_HOTDEAL   => Yii::t('main', 'Hotdeal'),
            self::STATUS_REDEEMED  => Yii::t('main', 'Hotdeal - Redeemed'),
        );
    }

    public function check_is_1st()
    {

        $first_time = FirstTimeApt::model()->findByAttributes(array('appointment_id' => $this->apt_id));

        if (NULL != $first_time)
        {
            return "<span class='label label-important'>1st</span>";
        }
        else
        {
            return '';
        }
    }

    public function getStatusLabel()
    {
        if (!$this->hasAttribute("status"))
            return '';

        $labelClass = 'label ';
        switch ($this->status)
        {
            case self::STATUS_PENDING:
                $labelClass .= 'label-info';
                break;
            case self::STATUS_REFUND:
                $labelClass .= '';
                break;
            case self::STATUS_CANCEL:
                $labelClass .= 'label-important';
                break;
            case self::STATUS_COMPLETED:
                $labelClass .= 'label-success';
                break;
            case self::STATUS_HOTDEAL:
                $labelClass .= 'label-warning';
                break;
            case self::STATUS_REDEEMED:
                $labelClass .= 'label-warning';
                break;
            default:
                break;
        }
        $labels = self::getListStatus();
        $label  = isset($labels[$this->status]) ? $labels[$this->status] : $this->status;
        return "<span class='$labelClass'>$label</span>";
    }

    public static function getListTypeArray()
    {
        return array(
            array('kfield' => 'hotdeal_discount', 'name' => Yii::t('main', 'Hotdeal')),
            array('kfield' => 'first_discount', 'name' => Yii::t('main', '1st trial')),
            array('kfield' => 'other_discount', 'name' => Yii::t('main', 'Other discount')),
        );
    }

    public function getListType()
    {
        $arr_result                   = array();
        if ($this->hotdeal_discount != "" && $this->hotdeal_discount > 0)
            $arr_result['hotdeal']        = true;
        if ($this->first_discount != "" && $this->first_discount > 0)
            $arr_result['thefirst']       = true;
        if ($this->other_discount != "" && $this->other_discount > 0)
            $arr_result['other_discount'] = true;
        return $arr_result;
    }

    public function getTypeLabel()
    {
        $labelClass = 'label ';
        $label      = "";
        if ($this->hotdeal_discount != "" && $this->hotdeal_discount > 0)
        {
            $labelClass1 = $labelClass . 'label-info';
            $label.="<span class='$labelClass1'>" . Yii::t('main', 'Hotdeal') . "</span>";
        }

        if ($this->first_discount != "" && $this->first_discount > 0)
        {
            $labelClass1 = $labelClass . 'label-warning';
            $label.="<span class='$labelClass1'>" . Yii::t('main', '1st trial') . "</span>";
        }

        if ($this->other_discount != "" && $this->other_discount > 0)
        {
            $labelClass1 = $labelClass . '';
            $label.="<span class='$labelClass1'>" . Yii::t('main', 'Other discount') . "</span>";
        }

        return $label;
    }

    public function formartDate()
    {
        echo date('D d/m/Y', $this->order_date);
    }

    function genOkey()
    {
        // Prefix của ukey
        $prefix = 'ODR';

        // Chuỗi số của ukey
        $result = crc32($this->order_id);
        if ($result < 0)
        {
            $result = '0' . abs($result);
        }
        $key = trim(sprintf("%012d", $result));

        return "$prefix-$key";
    }

    public function tax()
    {
        echo '$0.00';
    }

    public function totalTips()
    {
        echo '$0.00';
    }

    /**
     * 
     * @param int $apt_id of customer
     * @param int $cus_id id of customer
     */
    public static function createOrder($apt_id, $cus_id, $status_order, $hotdeal_discount = 0, $returnID = FALSE)
    {
        $ckey = Customer::getCkeybyId($cus_id);

        $order = Orders::model()->find('apt_id=:apt AND cus_ckey=:ckey', array(
            ':apt'  => $apt_id,
            ':ckey' => $ckey
        ));
        if ($order)
        {
            return $order->order_id;
        }
        else
        {
            $order                 = new Orders();
            $order->apt_id         = $apt_id;
            $order->cus_ckey       = $ckey;
            $order->order_date     = time();
            $order->payment_method = Orders::PAYMENT_CASH;

            if ($status_order == NULL)
            {
                $order->status = Orders::STATUS_PENDING;
            }
            else
            {
                $order->status = $status_order;
            }

            $apt                     = Appoint::model()->findByPk($order->apt_id);
            $order->s_id             = $apt->service_id;
            $order->staff_id         = $apt->author_id;
            $order->biz_id           = $apt->service->author_id;
            $order->s_price          = $apt->service->price;
            $order->hotdeal_discount = @$hotdeal_discount;
            //Tax của merchant
            $order->tax              = 0;
            if ($order->save())
            {
                $order->order_key = $order->genOkey();
                $order->update();
                return $returnID ? $order->order_id : TRUE;
            }
            else
            {
                return FALSE;
            }
        }
    }

    public static function countBooking()
    {
        $user           = Users::model()->findByPk(Yii::app()->user->getId());
        $cri            = new CDbCriteria();
        $cri->condition = 't.type!=' . Appoint::TYPE_BLOCK_TIME;
        if ($user->type == Users::TYPE_ADMIN)
        {
            
        }
        if ($user->type == Users::TYPE_BUSINESS)
        {
            $cri->with = array('service', 'service.user');
            $cri->compare('user.id', $user->id);
        }
        $count = Appoint::model()->count($cri);

        return $count;
    }

    public static function checkAddedStaff($ukey, $order_id)
    {
        $model = PerformOrder::model()->find('order_id=:odr AND staff_ukey=:ukey', array(
            ':odr'  => $order_id,
            ':ukey' => $ukey
        ));
        if ($model)
        {
            return TRUE;
        }
        return FALSE;
    }

    public static function getCustomerBookingIn7Week($new = false)
    {
        $array_order_in_7week  = array();
        $array_order_out_7week = array();
        $array_data            = array();

        //array đầu tuần của 7 tuần vừa qua
        $list_recent_7wk = Utils::_getRecent7Week();

        foreach ($list_recent_7wk as $key => $start_date)
        {
            //array CN của 7 tuần vừa qua
            $end_date = strtotime('next sunday', $start_date);

            //lấy order trong 7 tuần vừa qua
            $order_in_7week = self::getOrderIn7Week($start_date, $end_date);

            //lấy ckey của customer đã booking trong 7 tuần qua
            foreach ($order_in_7week as $vl)
            {
                $array_order_in_7week[] = $vl->cus_ckey;
            }

            //lấy order khác không nằm trong 7 tuần gần đây
            $order_out_7week = self::getOrderOut7Week($start_date, $end_date, $array_order_in_7week);

            //lấy ckey của customer theo $order_out_7week
            foreach ($order_out_7week as $vle)
            {
                $array_order_out_7week[] = $vle->cus_ckey;
            }

            $crit            = new CDbCriteria();
            $crit->condition = "(order_date BETWEEN '$start_date' AND '$end_date')";
            if ($new == false)
            {
                if ($array_order_out_7week != null)
                {
                    $crit->addInCondition('cus_ckey', array_intersect($array_order_in_7week, $array_order_out_7week));
                    $count_cus = Orders::model()->count($crit);
                }
                else
                {
                    $count_cus = 0;
                }
            }
            else
            {
                if ($array_order_out_7week != null)
                {
                    $crit->addNotInCondition('cus_ckey', array_intersect($array_order_in_7week, $array_order_out_7week));
                    $count_cus = Orders::model()->count($crit);
                }
                else
                {
                    $count_cus = count($array_order_in_7week);
                }
            }
            $array_data[] = array($key, $count_cus);
        }

        return json_encode($array_data);
    }

    public static function getOrderOut7Week($start_date, $end_date, $array_order_in_7week)
    {
        $crite            = new CDbCriteria();
        $crite->condition = "order_date < $start_date or order_date > $end_date";
        $crite->addInCondition('cus_ckey', $array_order_in_7week);
        return Orders::model()->findAll($crite);
    }

    public static function getOrderIn7Week($start_date, $end_date)
    {
        /*
         * Phân quyền
         */
        $user = Users::model()->findByPk(Yii::app()->user->getId());
        $cri  = new CDbCriteria();
        if ($user->type == Users::TYPE_ADMIN)
        {
            $cri->condition = "(order_date BETWEEN '$start_date' AND '$end_date')";
        }
        else
        {
            $array_staff = array();
            if ($user->type == Users::TYPE_BUSINESS)
            {
                $crite            = new CDbCriteria();
                $crite->condition = 'author_id = :a';
                $crite->params    = array(
                    ':a' => $user->id
                );
                $staffs           = Users::model()->findAll($crite);

                foreach ($staffs as $value)
                {
                    $array_staff[] = $value->id;
                }
                $cri->condition = "(order_date BETWEEN '$start_date' AND '$end_date')";
                $cri->addInCondition('staff_id', $array_staff);
            }
            else
            {
                $biz = Users::model()->find('id=:i', array(':i' => $user->id));

                $crit            = new CDbCriteria();
                $crit->condition = 'author_id =:a';
                $crit->params    = array(
                    ':a' => $biz->author_id
                );
                $staffs          = Users::model()->findAll($crit);
                foreach ($staffs as $value)
                {
                    $array_staff[] = $value->id;
                }
                $cri->condition = "(order_date BETWEEN '$start_date' AND '$end_date')";
                $cri->addInCondition('staff_id', $array_staff);
            }
        }
        return Orders::model()->findAll($cri);
    }

    public function getStaffsPerform()
    {
        $text = '';
        if ($this->performs)
        {
            foreach ($this->performs as $perform)
            {
                $staff = Users::getRecordByUkey($perform->staff_ukey);
                $text.=$staff->name . ', ';
            }
            return rtrim($text, ', ');
        }
        return $this->staff->name;
    }

}
